package com.springboot.securtiy.config;

import com.springboot.securtiy.filter.ParamhodlerFilter;
import com.springboot.securtiy.filter.VerificationCodeFilter;
import com.springboot.securtiy.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PasswordEncoder password1;

    @Autowired
    private PasswordEncoder myPasswordEncoder;

    @Autowired
    private UserDetailsService userServerImpl;

    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    @Autowired
    private ParamhodlerFilter paramhodlerFilter;

    @Autowired
    private SecurityAuthenticationFailureHandler securityAuthenticationFailureHandler;

    @Autowired
    private SecurityLogoutSuccessHandler securityLogoutSuccessHandler;

    @Autowired
    private SecurityAuthenticationEntryPoint securityAuthenticationEntryPoint;

    @Autowired
    private VerificationCodeFilter verificationCodeFilter;

    @Autowired
    private UserDetailsService userDetailsService;

    @Value("${spring.security.remember-me.key}")
    private String remberMeKey;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        String password = password1.encode("123");
//        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("admin").password(password).roles("admin");
        auth.userDetailsService(userServerImpl).passwordEncoder(myPasswordEncoder);//自定义验证 加密/密码比对
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 配置请求相关内容
        http.formLogin()
                .loginPage("/login/page").permitAll()// 登录页面地址，默认 /login, 这里的地址要由 controller
                .loginProcessingUrl("/login")
                .usernameParameter("name") // 登录页面用户名字段
                .passwordParameter("password") // 登录页面用户密码字段
                /*.defaultSuccessUrl("/LoginSuccess")*/.successHandler(myAuthenticationSuccessHandler)
                /*.failureUrl("/login/fail");*/.failureHandler(securityAuthenticationFailureHandler)
                .and()
                .logout()
                .logoutUrl("/user/logout")
                .logoutSuccessHandler(securityLogoutSuccessHandler)
                .invalidateHttpSession(true) //清除session
                .clearAuthentication(true) //清除认证信息
                .deleteCookies("cookie01","cookie01") //删除指定cookie
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                //未登录时的处理器
                .authenticationEntryPoint(securityAuthenticationEntryPoint)
                .and()
                .rememberMe()//实现自动登陆
                .userDetailsService(userDetailsService)
                .key(remberMeKey)
//                .tokenRepository().rememberMeServices();
                .and()
                //会话管理
                .sessionManagement()
                .sessionFixation()
                .migrateSession().maximumSessions(1);


//        http.logout()
//                .logoutUrl("/logout")
//                .logoutSuccessUrl("/logout.html")/*.logoutSuccessHandler(securityLogoutSuccessHandler)*/;

        http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);//403异常处理

        http.authorizeRequests().antMatchers("/captcha.jpg").permitAll()
                .antMatchers("/*").authenticated()
                .anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");
//                .permitAll();
        // 关闭csrf
//        http.csrf().disable();
        http.addFilterBefore(verificationCodeFilter, UsernamePasswordAuthenticationFilter.class); //自定义过滤器
        http.cors(); //开启跨域
    }
}
